package uit.compile.lexical;
import java.io.*;

public class Scanner {
    private static final char EOF = '\u0000';
    ErrorReporter reporter;
    SourcePosition position;
	ScannerBuffer buff;
	int state = 0;
	
    public Scanner() {
    	position = new SourcePosition();
    }

    public Scanner(String fileName, ErrorReporter er) {
    	reporter = er;
    	position = new SourcePosition(); 	
        buff = new ScannerBuffer(fileName);
    }
  
    private char nextChar() 
    {
    	position.charFinish++;
    	return buff.nextChar();
    }

    public Token nextToken()
    {
    	Token result = null;
    	state = 0;
    	char c = ' ';
    	String lexeme = null;
    	while (true)
    	{
    		switch (state)
    		{
    		case 0:
                c = nextChar();
                if (c == ' ' || c == '\t' || c == '\r'|| c == '\n')
                 {
                    if (c == '\n') 
                    { 
	                    position.newLine();	                    
	          	    }
	          	    else
	          	    if (c == '\t')
	          	    {
	          	    	position.charStart += 8; 
	          	    	position.charFinish += 7;
	          	    }
	                else
	                {	                	
	                	position.charStart++;//charFinish has already increased by 1
	                }
	                      		
    		}
                //--------------------------------------------------
                 
    		}
    	}
    }  
}

class ScannerBuffer{
    private static final char EOF = '\u0000';
	BufferedReader bufferedReader;
	ScannerBuffer(String fileName){
		try{
	        File file = new File(fileName);
	        FileReader reader = new FileReader(file);
	        bufferedReader = new BufferedReader(reader);
	        bufferedReader.mark(128);//mark the beginning of input buffer
	    }
		catch (Exception e)
        {}
	}
    public char nextChar() {
    	char result = EOF;
    	try{
	    	int r;
    		bufferedReader.mark(128);	    		
	    	if ((r = bufferedReader.read())!=-1)
	    	{
	    		result =  (char)r;
	    	}
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
    public void goBackOneCharacter(){
        reset();
    }
    public void reset(){
        try{
        	bufferedReader.reset();
        }
        catch (Exception e){
        }
    }
    public char goAheadOneCharacter(){
    	char result = EOF;
        try{
        	int r;
	    	if ((r = bufferedReader.read())!=-1)
	    	{
	    		result =  (char)r;
	    	}
        }
        catch (Exception e){
        }    
        return result;
    }
}
